
#include <inttypes.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

int strcmp(char const*, char const*);

# include "native_array.h"
# include "native_stack.h"
# include "string.h"
# include "new.h"


void test_eq()
{
    Object* null_string = new(String, NULL),
          * zero_string = new(String, ""),
          * str = new(String, "bite"),
          * str2 = new(String, "bite"),
          * str3 = new(String, "tibe");
    assert(eq(null_string, zero_string));
    assert(eq(zero_string, zero_string));
    assert(eq(zero_string, null_string));
    assert(eq(null_string, null_string));
    assert(eq(str, str2));
    assert(eq(str2, str));
    assert(!eq(str, str3));
    assert(!eq(str3, str));
    delete_all(null_string, zero_string, str, str2, str3);
}

void test_gtlt()

{
    Object* empty = new(String, ""),
          * a = new(String, "aaaaaaa"),
          * b = new(String, "b"),
          * c = new(String, "cc");
    assert(lt(empty, a) == true);
    assert(lt(empty, b) == true);
    assert(lt(empty, c) == true);
    assert(lt(empty, empty) == false);
    assert(gt(empty, empty) == false);
    assert(lt(a, b) == true);
    assert(lt(b, c) == true);
    assert(lt(a, c) == true);
    assert(lt(a, a) == false);
    assert(gt(c, a) == true);
    assert(gt(b, a) == true);
    assert(gt(a, a) == false);
    delete_all(empty, a, b, c);
}

void test_add()
{
    Object* empty = new(String, ""),
          * null = new(String, NULL),
          * s1 = new(String, "s1"),
          * s2 = new(String, "s2");
    assert(size(empty) == 0);
    assert(size(null) == 0);
    assert(size(s1) == 2);
    assert(size(s2) == 2);
    assert(size(add(empty, null)) == 0);
    assert(size(add(null, empty)) == 0);
    assert(size(add(empty, s1)) == 2);
    assert(size(add(null, s1)) == 2);
    assert(size(add(s1, empty)) == 2);
    assert(size(add(s1, null)) == 2);
    assert(size(add(s1, s2)) == 4);

    assert(strcmp(str(add(empty, null)), "") == 0);
    assert(strcmp(str(add(null, empty)), "") == 0);
    assert(strcmp(str(add(empty, s1)), "s1") == 0);
    assert(strcmp(str(add(null, s1)), "s1") == 0);
    assert(strcmp(str(add(s1, empty)), "s1") == 0);
    assert(strcmp(str(add(s1, null)), "s1") == 0);
    assert(strcmp(str(add(s1, s2)), "s1s2") == 0);

    clean_all();
}

int main()
{
    Object * s1 = new(String, "piff"),
           * s2 = new(String, "Word");

    for (int i = 0; i < 10; ++i)
        push_back(s1, ' ');

    push_back(s2, ' ');
    push_back(s2, 'b');
    push_back(s2, 'i');
    push_back(s2, 't');
    push_back(s2, 'e');
    Object* sum = add(s1, s2);
    printf("s1: '%s' (len = %u)\n",str(s1), size(s1));
    printf("s2: '%s' (len = %u)\n",str(s2), size(s2));
    printf("s1 + s2 = %s (len = %u)\n", str(sum), size(sum));
    printf("s2[0] = %c\n", front_char(s2));
    printf("s2[-1] = %c\n", back_char(s2));
    for (size_t i = 0; i < size(s2); ++i)
        printf("s2[%d] = %c\n", i, getitem_char(s2, i));

    clear(s1);
    delete_all(s1,s2,sum);

    test_eq();
    test_gtlt();
    test_add();
    return 0;
}
